<html>
	<head>
		<!-- Update title -->
		<title>OpenGL in Cinder: Textures</title>

   		<!-- master stylesheet - these links will be replaced when compiled -->
		<link rel="stylesheet" href="../../_assets/css/foundation.css">
		<link rel="stylesheet" href="../../_assets/css/prism.css">
		<link rel="stylesheet" href="../../_assets/css/style.css">
		<link href='http://fonts.googleapis.com/css?family=Open+Sans:400,300,600,700' rel='stylesheet' type='text/css'>
	</head>

<body id="guide-contents" >

<a id="textures"></a>
<h2>Textures</h2>
<p>Images in OpenGL generally take the form of <em>textures</em>, and Cinder exposes this functionality through the class <ci>gl::Texture2d</ci> and its siblings. Let's look at a basic example:</p>

<div class="cols-2">
<div class="col">
<pre><code class="lang-cpp">
class BasicApp : public App {
  public:
	void setup() override;
	void draw() override;
	
	gl::Texture2dRef		mTex;
};

void BasicApp::setup()
{
	auto img = loadImage( loadAsset( "clouds.jpg" ) );
	mTex = gl::Texture2d::create( img );
}

void BasicApp::draw()
{
	gl::clear();

	gl::draw( mTex );
}
</code></pre>
</div>
<div class="col">
<img src="images/clouds_example.jpg" class="shadow" />
</div>
</div>

<p>We're using an <a href="https://www.flickr.com/photos/stuckincustoms/20154632802/">image from Trey Ratcliff</a> that's saved in our application's <code>assets</code> directory as <em>"clouds.jpg"</em>. We call <ci>loadImage()</ci> using this asset and then pass the result to the variant of <ci dox="gl::Texture2d::create(const ImageSourceRef &img)">gl::Texture2d::create()</ci> which accepts an <ci>ImageSource</ci>.</p>

<p>Besides simply drawing a texture, we often want to apply one (or more) to the vertices of a 2D or 3D model - a process known as <em>texturemapping</em>. Let's look at a simple example of this in Cinder:</p>

<div class="cols-2">
<div class="col">
<pre><code class="lang-cpp">
class BasicApp : public App {
  public:	
	void	setup() override;
	void	draw() override;
	
	CameraPersp			mCam;
	gl::BatchRef		mSphere;
	gl::TextureRef		mTexture;
	gl::GlslProgRef		mGlsl;
};

void BasicApp::setup()
{
	mCam.lookAt( vec3( 3, 2, 4 ), vec3( 0 ) );
	
	auto img = loadImage( loadAsset( "checkerboard.png" ) );
	mTexture = gl::Texture::create( img );
	mTexture->bind();

	auto shader = gl::ShaderDef().texture().lambert();
	mGlsl = gl::getStockShader( shader );
	auto sphere = geom::Sphere().subdivisions( 50 );
	mSphere = gl::Batch::create( sphere, mGlsl );
	
	gl::enableDepthWrite();
	gl::enableDepthRead();
}

void BasicApp::draw()
{
	gl::clear( Color( 0.2f, 0.2f, 0.2f ) );
	gl::setMatrices( mCam );

	mSphere->draw();

	// draw the texture itself in the upper right corner	
	gl::setMatricesWindow( getWindowSize() );
	Rectf drawRect( 0, 0, mTexture->getWidth() / 3,
						mTexture->getHeight() / 3 );
	gl::draw( mTexture, drawRect );
}
</code></pre>
</div>
<div class="col">
<img src="images/textured_sphere.png" class="shadow" />
</div>
</div>

<p>In this example we load the texture from a file called <em>checkerboard.png</em>, similar to the previous example. However in this case, we're setting up a <ci>gl::GlslProg</ci> from a <ci>gl::ShaderDef</ci> with both <ci dox="gl::ShaderDef::lambert">lambert()</ci> and <ci dox="gl::ShaderDef::texture">texture()</ci> applied. Another key distinction is that we're calling the <ci dox="gl::Texture2d::bind">bind()</ci> method on <em>mTexture</em>. Binding a texture is simply making it the active texture. We do this from <code>setup()</code> because we only ever bind one texture. In the <code>draw()</code> method we draw the sphere by calling <code>mSphere->draw()</code>. Finally, we draw the texture itself for illustration purposes. Notice that before we do so, we use <ci>gl::setMatricesWindow()</ci> to restore our <code>View</code> and <code>Perspective</code> matrices to the window-aligned defaults. Also note that we're using the <ci dox="gl::draw(const TextureRef&, const Rectf&)">gl::draw()</ci> variant that accepts a <ci>Rectf</ci> which the texture is mapped to.</p>

<script src="../../_assets/js/prism.js" type="text/javascript"></script>
</body>
</html>